<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        .comp-a,
        .comp-b,
        .comp-c {
            line-height: 40px;
            padding: 10px;
            margin: 10px auto;
            border: 1px dashed #333;
        }
    </style>
</head>

<body>
    <!-- 根组件 -->
    <div id="app">
        <p>count:{{count}}</p>
        <p><button @click="count++">count++</button></p>
        <hr>
        <laowang-clock></laowang-clock>
        <laowang-a></laowang-a>
    </div>
</body>
<script>
    /*  
        !!! 在Vue中,每一个组件都是一个vue实例, 有自己的配置项(data methods template computed watch 生命周期钩子)    

        Vue中如何定义组件?  

        1.  全局组件  => 一次注册,多次使用
            Vue.component(componentName,option)
                componentName  组件名称(字符串)
                    组件名称推荐使用, 中划线命名法 和 大驼峰命名法
                        中划线命名法:  laowang-clock
                        大驼峰命名法:  LaowangClock


                option 组件相关配置 (包含data methods computed watch 生命周期钩子)   


            优点:
                一次注册,多次使用(当前页面任何位置)

            缺点:
                1. 组件之间的依赖关系不是很明显 
                2. 全局组件一经注册,不管是否使用, 都会保留到打包后的源码中 (Vue项目)



        2.  局部组件    
            如何使用局部组件
            a. 通过javascript 对象数据定义组件  (只是相当于提前准备好了组件的配置项)
            b. 在父组件中配置components选项 => 引入需要依赖的组件(子组件)
                对象的键名: 就是局部组件的组件名
                对象的键值: 局部组件的配置项

                1. 局部组件使用时才会被注册 (全局组件在页面加载时就已经被提前注册)
                2. 局部组件依赖关系比较明确
                3. 如果一个局部组件没有被其他使用, 会在项目打包时,删除该组件




        Vue中如何使用组件?
            1. 对应组件名称, 在需要使用组件的组件, 创建自定义标签   => 该自定义标签,会在组件挂载时, 替换为template中的元素
            2. Vue2中, 组件命名时,可以使用 中划线命名法 和 大驼峰命名法, 但是组件使用时推荐使用 中划线命名法


        组件之间的层级关系
            根组件  父组件 子组件  兄弟组件

        组件注册注意:
            1. 在Vue中,每一个组件都是一个vue实例, 有自己的配置项(data methods template computed watch 生命周期钩子)   
            2. data选项要求是一个返回对象的函数
            3. 单个根元素 (组件的模板只能有一个根元素 => Vue2要求,  Vue3无所谓)
    
    */


    // (1) 通过对象将组件的配置存储起来

    let LaowangClock = {
        template: `<div class="show-time">
            {{year}}-{{month}}-{{day}}  {{hour}}:{{min}}:{{sec}}
        </div>`,

        // 此写法有误 => 组件复用时, 使用共有一个data选项
        // data:{
        //     // now: new Date("2024-1-1 00:00:00"),
        //     now: new Date(),
        //     timer: null,
        // },

        // 为保证组件复用时数据分离(让每一个组件都有其自己独立的数据), 在组件初始化阶段会调用data函数,将函数返回的对象作为挂载的数据
        data: function () {
            return {
                // now: new Date("2024-1-1 00:00:00"),
                now: new Date(),
                timer: null,
            }
        },
        methods: {
            update() {
                clearInterval(this.timer);
                this.timer = setInterval(() => {
                    this.now = new Date();
                }, 1000)
            },
            stop() {
                clearInterval(this.timer);
            }
        },
        computed: {
            year() {
                return this.now.getFullYear();
            },
            month() {
                // 月份参数: 0 - 11 
                // 实际月份 = 月份参数 + 1
                var month = this.now.getMonth() + 1
                return month.toString().padStart(2, "0");
            },
            day() {
                var day = this.now.getDate()
                return day.toString().padStart(2, "0");
            },
            hour() {
                var hour = this.now.getHours();
                return hour.toString().padStart(2, "0");
            },
            min() {
                var min = this.now.getMinutes();
                return min.toString().padStart(2, "0");
            },
            sec() {
                var sec = this.now.getSeconds();
                return sec.toString().padStart(2, "0");
            },
            dateOption() {
                var year = this.now.getFullYear();
                var month = this.now.getMonth() + 1;
                var day = this.now.getDate();
                var hour = this.now.getHours();
                var min = this.now.getMinutes();
                var sec = this.now.getSeconds();
                return {
                    year: year,
                    month: month.toString().padStart(2, "0"),
                    day: day.toString().padStart(2, "0"),
                    hour: hour.toString().padStart(2, "0"),
                    min: min.toString().padStart(2, "0"),
                    sec: sec.toString().padStart(2, "0"),
                }
            }
        },
        mounted() {
            console.log(this);
            this.update();
        },
        beforeDestroy() {
            this.stop();
        }
    }


    let LaowangB = {
        template: `<div class="comp-b">
                    这是B组件
                </div>`
    }


    let LaowangC = {
        template: `<div class="comp-c">
                    这是C组件
                </div>`
    }

    let LaowangA = {
        template: `<div class="comp-a">
                    这是A组件
                    <laowang-b></laowang-b>
                    <laowang-c></laowang-c>
                </div>`,
        components:{
            LaowangB:LaowangB,
            LaowangC:LaowangC,
        }
    }


    // 根组件 => 挂载到页面最外层中 (所有组件,都是根组件的子组件)
    var vm = new Vue({
        el: "#app",
        data: {
            count: 1,
        },
        components:{
            // components 局部组件注册 (使用时才会被注册)
            // 对象的键名: 就是局部组件的组件名
            // 对象的键值: 局部组件的配置项 
            LaowangClock:LaowangClock,
            "laowang-a": LaowangA
        }
    })



</script>

</html>